<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <title>SVG SCADA - Hot Water Temperature &amp; Pump ON/OFF</title>
  <script type="text/javascript" src="../../../highlight.pack.js"></script>
  <script type="text/javascript" src="../../../highlightCode.js"></script>
  <link href='../../../highlight.css' rel='stylesheet' />

  <script type="text/javascript" src="analogGaugeObject.js"></script>
 <script src="https://d3js.org/d3.v4.min.js"></script>
 <script type="text/javascript" src="svg.js"></script>

<script src="https://cdn.pubnub.com/sdk/javascript/pubnub.4.20.2.js"></script>



<meta http-equiv="content-type" content="text/html; charset=UTF-8">
</head>
<body  style='padding:10px;font-family:arial;overflow:hidden'>
     <div id=container>

<center>
<h4>2.) SVG SCADA - Hot Water Temperature &amp; Pump ON/OFF </h4>
<div style='width:90%;background-color:gainsboro;text-align:justify;padding:10px;border-radius:6px;'>

   This shows a real-time interactive SVG SCADA drawing of a building's heating hot water system. A field temperature
   transmitter is sending its data over the DSN to the temperature gauge in the SVG SCADA drawing. An ON/OFF button
   provides the ability for the SCADA operator to turn the pump on or off.

</div>
<table>
<tr>
<td valign=top>
<div  style="width:400px;text-align:justify;padding:10px">
   <b>Sequence Of Operation:</b><p></p>
  Initially the hot water pump is shown as "OFF" at the button.

  As the operator, you can click the button to request the
  pump be turned "ON".<p></p>


  When the operator requests the pump ON action, the message "ON" is <b>published</b> via DSN. The  SVG SCADA drawing <b>subscribes</b> to the data.
  When the message is received via DSN, the SVG SCADA changes the button status display from OFF(red) to ON(green).
   Also the pump's impeller symbol will then be rotating, and flow arrows will move along the hot water piping.

<p></p>
 When the pump is ON (green),
 The data from the field-mounted temperature transmitter is <b>published</b> over the DSN every two(2) seconds. The  SVG SCADA drawing <b>subscribes</b> to the data, and the dial of the temperature gauge moves to display the data.

 </div>
</td>
<td>
<div id="svgDiv" style='border:1px solid black;width:550px;height:300px;'>
<svg xmlns="http://www.w3.org/2000/svg" id="mySVG" width="550" height="300" viewBox="0 0 550 300" style="touch-action: none; -webkit-tap-highlight-color: rgba(0, 0, 0, 0);"><style xmlns="http://www.w3.org/1999/xhtml"></style><defs xmlns="http://www.w3.org/1999/xhtml"></defs>

<g id="publishG"><g id="publishElemG" shape-rendering="geometricPrecision" text-rendering="geometricPrecision">
    <path id="pipe" fill="none" fill-opacity="1.0" stroke="#ADFF2F" stroke-width="15" stroke-opacity="1.0" d="M 335 58 L 335 38 L 496 38 L 496 118 L 434 118 L 434 211 L 238 211 L 238 261 L 48 261 L 48 56 L 335 56 z" filter="url(#pipe3D)" stroke-linejoin="round" rightAngle="true" rotateAngle="0"/>
<g id='pathArrowsG' />
<g xmlns="http://www.w3.org/2000/svg" transform="matrix(-1 0 0 1 482.9 185)" parentid="componentISA141">
		<path stroke="#000000" d="M27.5,0L0,0L0,37.6L27.5,37.6L27.5,0z" transform="translate(2.44,5.75)" fill="#FF0000" id="shape1" fill-opacity="1"/>
		<path stroke="#000000" d="M0,0L108.5,0L108.5,37.6L0,37.6L0,0z" transform="translate(32.08,5.72)" fill="#FF0000" id="shape2" fill-opacity="1"/>
		<g transform="translate(11.41,0)">
			<path stroke="#000000" d="M0,5.7L0,0" transform="translate(4.28,0)" fill="none" id="shape3"/>
			<path stroke="#000000" d="M0,0L8.1,0" transform="translate(0,0)" fill="none" id="shape4"/>
		</g>
		<g transform="translate(41.56,0)">
			<path stroke="#000000" d="M0,5.7L0,0" transform="translate(4.28,0)" fill="none" id="shape5"/>
			<path stroke="#000000" d="M0,0L8.1,0" transform="translate(0,0)" fill="none" id="shape6"/>
		</g>
		<g transform="matrix(1,0,0,-1,11.4,49.2)">
			<path stroke="#000000" d="M0,5.7L0,0" transform="translate(4.28,0)" fill="none" id="shape7"/>
			<path stroke="#000000" d="M0,0L8.1,0" transform="translate(0,0)" fill="none" id="shape8"/>
		</g>
		<g transform="matrix(1,0,0,-1,123.7,49.2)">
			<path stroke="#000000" d="M0,5.7L0,0" transform="translate(4.28,0)" fill="none" id="shape9"/>
			<path stroke="#000000" d="M0,0L8.1,0" transform="translate(0,0)" fill="none" id="shape10"/>
		</g>
		<path stroke="#000000" d="M0,0L0,48.2" transform="translate(29.74,0.2)" fill="none" id="shape11"/>
		<path stroke="#000000" d="M0,0L0,48.2" transform="translate(32.19,0.2)" fill="none" id="shape12"/>
		<path stroke="#000000" d="M0,0L0,48.2" transform="translate(0,0.44)" fill="none" id="shape13"/>
		<path stroke="#000000" d="M0,0L0,48.2" transform="translate(2.44,0.44)" fill="none" id="shape14"/>
		<path stroke="#000000" d="M27.1,0L7.7,0C7.7,0,-0,.4,-0,18.8C-0,37.1,7.7,37.6,7.7,37.6L27.1,37.6L27.1,0z" transform="matrix(-1,0,0,1,169.9,5.8)" fill="#FF0000" id="shape15" fill-opacity="1"/>
		<path stroke="#000000" d="M0,0L0,48.2" transform="translate(140.41,0.44)" fill="none" id="shape16"/>
		<path stroke="#000000" d="M0,0L0,48.2" transform="translate(142.86,0.44)" fill="none" id="shape17"/>
		<rect fill="white" fill-opacity="0" style="cursor: default;" width="169.89999389648438" height="49.20000076293945" vector-effects="non-scaling-stroke" stroke-width="6" stroke-opacity=".5"/></g><g title="Horizontal Pump" parentid="" transform="matrix(0.55 0 0 0.55 292.15 26.15)"><svg xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" title="Horizontal Pump" class="Pumps" height="106" width="154" viewBox="0 0 154 105.947" nativewidth="154" nativeheight="106" overflow="visible" myscale="1.0">
    <defs>
        <linearGradient x1="0%" y2="0%" x2="100%" y1="0%" id="lg1_219">
            <stop stop-color="#9aa1aa" offset="0"/>
            <stop stop-color="#aeb5c0" offset="0.22"/>
            <stop stop-color="#dce0e5" offset="0.57"/>
            <stop stop-color="#cacfd7" offset="0.84"/>
            <stop stop-color="#a7afb9" offset="1"/>
        </linearGradient>
        <linearGradient x1="0%" y2="0%" x2="100%" y1="0%" id="lg2_219">
            <stop stop-color="#8f969d" offset="0"/>
            <stop stop-color="#d3d8de" offset="0.64"/>
            <stop stop-color="#9aa0a8" offset="1"/>
        </linearGradient>
        <linearGradient x1="0%" y2="0%" x2="100%" y1="0%" id="lg3_219">
            <stop stop-color="#626974" offset="0"/>
            <stop stop-color="#ccd0d5" offset="0.66"/>
            <stop stop-color="#5e6670" offset="1"/>
        </linearGradient>
        <radialGradient fy="51" r="72.6" id="rg1" cy="51" cx="51" gradientUnits="userSpaceOnUse" fx="51">
            <stop stop-color="#c7cbd1" offset="0"/>
            <stop stop-color="#c4c7cd" offset="0.91"/>
            <stop stop-color="#d4d8dd" offset="0.74"/>
            <stop stop-color="#b6bcc4" offset="0.54"/>
        </radialGradient>
    </defs>
    <g transform="translate(1.01,1)">
        <g transform="matrix(-1,0,0,1,74.4,31.2)">
            <path transform="matrix(0,-1,-1,0,68.3,40.6)" id="shape1" fill="url(#lg1_219)" d="M0,0L39.1,0L39.1,68.3L0,68.3L0,0z"/>
            <path transform="matrix(0,-1,-1,0,74.4,42.9)" id="shape2" fill="url(#lg2_219)" d="M1.4,-0L41.5,-0C42.2,-0,42.9,1.3,42.9,3C42.9,4.7,42.2,6.1,41.5,6.1L1.4,6.1C.6,6.1,0,4.7,0,3C0,1.3,.6,-0,1.4,-0z"/>
            <path transform="matrix(0,-1,-1,0,70.3,42.7)" id="shape3" fill="url(#lg3_219)" d="M42.5,0C42.4,1.1,41.9,1.9,41.1,1.9L1.4,1.9C.6,1.9,.1,1,0,0C0,0,42.5,0,42.5,0z"/>
            <path transform="matrix(0,-1,-1,0,74.1,42.2)" id="shape4" fill="#ffffff" fill-opacity="0.32" d="M.7,0L40.8,0C41.2,0,41.5,.3,41.5,.6C41.5,.9,41.2,1.1,40.8,1.1L.7,1.1C.3,1.1,0,.9,0,.6C0,.3,.3,0,.7,0z"/>
        </g>
        <g transform="translate(77.55,0)">
            <path transform="matrix(0,-1,-1,0,68.3,40.7)" id="shape5" fill="url(#lg1_219)" d="M0,0L39.1,0L39.1,68.3L0,68.3L0,0z"/>
            <path transform="matrix(0,-1,-1,0,74.4,42.9)" id="shape6" fill="url(#lg2_219)" d="M1.4,-0L41.5,-0C42.2,-0,42.9,1.3,42.9,3C42.9,4.7,42.2,6.1,41.5,6.1L1.4,6.1C.6,6.1,0,4.7,0,3C0,1.3,.6,-0,1.4,-0z"/>
            <path transform="matrix(0,-1,-1,0,70.3,42.7)" id="shape7" fill="url(#lg3_219)" d="M42.5,0C42.4,1.1,41.9,1.9,41.1,1.9L1.4,1.9C.6,1.9,.1,1,0,0C0,0,42.5,0,42.5,0z"/>
            <path transform="matrix(0,-1,-1,0,74.1,42.2)" id="shape8" fill="#ffffff" fill-opacity="0.35" d="M.7,0L40.8,0C41.2,0,41.5,.3,41.5,.6C41.5,.9,41.2,1.1,40.8,1.1L.7,1.1C.3,1.1,0,.9,0,.6C0,.3,.3,0,.7,0z"/>
        </g>
        <g transform="translate(26.19,1.31)">
            <path transform="matrix(0,-1,-1,0,102.8,102.6)" id="shape9" fill="url(#rg1)" stroke="#d4d6db" stroke-width="0.25" d="M0,51.4C0,23,23,0,51.3,0C79.7,0,102.6,23,102.6,51.4C102.6,79.8,79.7,102.8,51.3,102.8C23,102.8,0,79.8,0,51.4z"/>
            <path transform="matrix(0,-1,-1,0,94.2,94)" id="shape10" fill="#ffffff" fill-opacity="0.27" d="M0,42.7C0,19.1,19.1,0,42.6,0C66.2,0,85.3,19.1,85.3,42.7C85.3,66.3,66.2,85.5,42.6,85.5C19.1,85.5,0,66.3,0,42.7z"/>
            <path transform="matrix(0,-1,-1,0,85.9,93.9)" id="shape11" fill="#ffffff" fill-opacity="0.13" d="M0,34.5C-0.3,13,17.1,0,17.1,0L73.1,63.9C73.1,63.9,62.3,77.3,42.6,77.3C19.1,77.3,0,58.1,0,34.5z"/>
        </g>
    </g>
</svg><rect width="154" height="106" stroke="none" stroke-width="2" fill="white" fill-opacity="0" style="cursor: default;"/></g>
<g myScale=".4" transform="matrix(0.4 0 0 0.4 293 92)" myRotate="0" myStatus="off">
<g cursor="default">
<defs id="onOffButtonDefs"><filter id="onOffButtonDropShadow" height="40">
  <feGaussianBlur in="SourceAlpha" stdDeviation="10"/> <!-- stdDeviation is how much to blur -->
  <feOffset dx="6" dy="10" result="offsetblur"/> <!-- how much to offset -->
  <feMerge>
    <feMergeNode/> <!-- this contains the offset blurred image -->
    <feMergeNode in="SourceGraphic"/> <!-- this contains the element that the filter is applied to -->
  </feMerge>
</filter><linearGradient id="linearGradientOnOffButton">
      <stop style="stop-color:#000000;stop-opacity:0" offset="0"/>
      <stop style="stop-color:#000000;stop-opacity:0.5" offset="1"/>
    </linearGradient><linearGradient id="linearGradientOnOffButton2">
      <stop style="stop-color:#ffffff;stop-opacity:1" offset="0"/>
      <stop style="stop-color:#ffffff;stop-opacity:0" offset="1"/>
    </linearGradient><linearGradient x1="120" y1="10" x2="120" y2="50" id="linearGradientOnOffButtonHighlight" xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#linearGradientOnOffButton2" gradientUnits="userSpaceOnUse"/><radialGradient cx="120" cy="170" r="100" fx="120" fy="170" id="radialGradientOnOffButton" xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#linearGradientOnOffButton" gradientUnits="userSpaceOnUse" gradientTransform="matrix(0,-0.72727275,2,0,-220,170)"/>
  </defs>
  <rect  onClick="publishPump()" aria-pressed="false" fill="red" width="220" height="80" ry="40" x="10" y="10" id="ButtonBase" style="stroke:none" filter="url(#onOffButtonDropShadow)"/>
    <rect width="220" height="80" ry="40" x="10" y="10" id="ButtonGlow" pointer-events="none" style="fill:url(#radialGradientOnOffButton);stroke:none"/>
    <text x="120" y="66" id="buttonText" pointer-events="none" xml:space="preserve" style="font-size:40px;text-align:center;text-anchor:middle;fill:#000000;stroke:none;font-family:Sans">OFF</text>
    <text x="120" y="64.5" id="buttonTextOffset" pointer-events="none" xml:space="preserve" style="font-size:40px;text-align:center;text-anchor:middle;fill:#ffffff;stroke:none;font-family:Sans">OFF</text>
    <path d="m 50,15 140,0 c 11.08,0 22.51667,10.914008 20,20 C 208.16563,41.622482 201.08,40 190,40 L 50.00005,40 C 38.92005,40 31.834332,41.622512 30,35 27.483323,25.914009 38.92,15 50,15 z" id="ButtonHighlight" pointer-events="none" style="fill:url(#linearGradientOnOffButtonHighlight)"/>
  </g>
</g>

<g xmlns="http://www.w3.org/2000/svg" transform="matrix(0.3 0 0 0.3 122.7 124.2)" parentid="component1520525398327"><rect id="rect1520521353036" fill="white" fill-opacity="0" stroke="#000000" stroke-width="2" x="0" y="0" width="38" height="91" rx="10" ry="10" transform="matrix(1 0 0 1 60 407)"/><rect id="rect1520521382334" fill="#000000" fill-opacity="1.0" stroke="#000000" stroke-width="2" x="0" y="0" width="19" height="37" transform="matrix(1 0 0 1 69 370)"/><rect id="rect1520521416875" fill="white" fill-opacity="0" stroke="#000000" stroke-width="2" x="0" y="0" width="72" height="60" rx="10" ry="10" transform="matrix(1 0 0 1 45 309)"/><text id="text1520523964235" font-family="Arial" font-size="40" font-weight="bold" font-style="normal" stroke="none" stroke-width="0.8" fill="#000000" transform="matrix(1 0 0 1 52 352)" filter="null">TT</text><ellipse id="ellipse1520524088195" stroke="#FF0000" stroke-width="2" fill="white" fill-opacity="0" transform="matrix(1 0 0 1 77 456)" rx="11" ry="22"/><rect id="rect1520525024221" fill="#FF0000" fill-opacity="1.0" stroke="#FF0000" stroke-width="2" x="0" y="0" width="19" height="9" transform="matrix(1 0 0 1 68 479)"/><text id="text1520525215133" font-family="Arial" font-size="20" font-weight="normal" font-style="normal" stroke="none" stroke-width="0" fill="#000000" transform="matrix(1 0 0 1 60 519)">RTD</text><text id="icon1520524724060" font-size="45" font-family="Arial Unicode MS" stroke-width="0.9" fill="#FF0000" stroke="black" x="-6.53125" y="15" transform="matrix(1 0 0 1 76 455)" cursor="default">⦚</text><text id="icon1520524875331" font-size="30" font-family="Arial Unicode MS" stroke-width="0.6" fill="#0000FF" stroke="black" x="-14.84375" y="10.5" transform="matrix(1 0 0 1 76 422)" cursor="default">▼</text><rect width="72" height="214" fill="white" fill-opacity="0" transform="translate(45,309)" style="cursor: default;" vector-effects="non-scaling-stroke" stroke-width="6" stroke-opacity=".5"/></g>

<path fill="none" fill-opacity="1.0" stroke="#000000" stroke-width="1.5" stroke-opacity="1.0" stroke-dasharray="8 4" marker-end="url(#arrow000000)" d="M 146 217 L 146 169" rightAngle="true" rotateAngle="0"/><text font-family="Arial" font-size="20" font-weight="normal" font-style="normal" stroke="none" stroke-width="0" fill="#000000" transform="matrix(1 0 0 1 316 19)" rotateAngle="0">Pump</text><text font-family="Arial" font-size="20" font-weight="normal" font-style="normal" stroke="none" stroke-width="0.4" fill="#000000" transform="matrix(1 0 0 1 258 255)" rotateAngle="0" filter="null">Steam-to-Hot Water Converter</text></g></g><defs id="arrowDefs"><marker id="arrow000000" viewBox="0 0 8000 8000" vector-effect="non-scaling-stroke" refX="250" refY="150" markerUnits="strokeWidth" markerWidth="300" markerHeight="300" orient="auto" fill="#000000" stroke-linejoin="bevel"><path d="M2 59,293 148,1 243,121 151,Z" stroke="RGB(0,0,0)"/></marker><marker id="arrow663399" viewBox="0 0 8000 8000" vector-effect="non-scaling-stroke" refX="250" refY="150" markerUnits="strokeWidth" markerWidth="300" markerHeight="300" orient="auto" fill="#663399" stroke-linejoin="bevel"><path d="M2 59,293 148,1 243,121 151,Z" stroke="RGB(0,0,0)"/></marker></defs><defs id="pipe3dDefs"><filter id="pipe3D"><feFlood flood-color="black"/><feComposite operator="out" in2="SourceGraphic"/><feGaussianBlur stdDeviation="6"/><feComposite operator="atop" in2="SourceGraphic"/></filter></defs>
<g id="gaugeHWSGaugeContainer" transform='translate(145,105)' />

</svg>

</div>

</td>
</tr></table>

  <br><button title="Show Javascript Source" onclick=showSource()>Javascript Source</button> <button title="Close javascript source" disabled id=closeSourceButton onClick=closeSource()>X</button>

 <div id=sourceDiv style=overflow:auto;width:100%;height:1px;visibility:hidden;overflow:hidden>
  <br>Javascript:
  <div id=jsCodeDiv style=overflow:auto;width:90%;text-align:left; ></div>
</div>
</center>
     </div>
<script id=myScript>
//---JavaScript SDK  https://cdn.pubnub.com/sdk/javascript/pubnub.4.20.2.js ---

//--onload---
var pubnubPublish
function initPublish()
{
    pubnubPublish = new PubNub(
    {
        publishKey : 'pub-c-ea28c028-e01a-4d16-80ec-0ad017c8a0a1',
        subscribeKey : 'sub-c-0da31452-3beb-11e8-a60e-fec077c63a9e',
        ssl: true
   })

}

//---onload---
var pubnubSubscribeTemperature
function initSubscribeTemperature()
{
    pubnubSubscribeTemperature = new PubNub(
    {
        subscribeKey : 'sub-c-0da31452-3beb-11e8-a60e-fec077c63a9e',
        ssl: true
    })

    //**************the keys to kingdom*****************
    pubnubSubscribeTemperature.addListener(
    {
        message: function(m)
        {
            //---handle message---
            var channelName = m.channel; //---The channel for which the message belongs---
            var channelGroup = m.subscription; //---The channel group or wildcard subscription match (if exists)---
            var pubTT = m.timetoken; //---Publish timetoken---
            var msg = m.message; //---The Payload---
            console.log(msg)
            changeGaugeHWS(msg)
        }

    })
    //*****************************************************

    pubnubSubscribeTemperature.subscribe(
    {
        channels: [HWS] //---unique for this viewer "HWS"+timeStamp---
    })

}
//---onload---
var pubnubSubscribePump
function initSubscribePump()
{
    pubnubSubscribePump = new PubNub(
    {
        subscribeKey : 'sub-c-0da31452-3beb-11e8-a60e-fec077c63a9e',
        ssl: true
    })

    //**************the keys to kingdom*****************
    pubnubSubscribePump.addListener(
    {
        message: function(m)
        {
            //---handle message---
            var channelName = m.channel; //---The channel for which the message belongs---
            var channelGroup = m.subscription; //---The channel group or wildcard subscription match (if exists)---
            var pubTT = m.timetoken; //---Publish timetoken---
            var msg = m.message; //---The Payload---
            console.log(msg)
            pumpStatusChange(msg)
        }

    })
    //*****************************************************

    pubnubSubscribePump.subscribe(
    {
        channels: [PUMP]  //---unique for this viewer "PUMP"+timeStamp---
    })

}



var MessagePump="OFF"
//---operator clicks ON/OFF button---
function publishPump()
{
    if(MessagePump=="OFF")
        MessagePump="ON"
    else
        MessagePump="OFF"

    var publishConfig =
    {
        channel : PUMP,   //---unique for this viewer "PUMP"+timeStamp---
        message :MessagePump
    }
    pubnubPublish.publish(publishConfig, function(status, response)
    {
        console.log(status, response);
    })
}

//---status: Message received---
function pumpStatusChange(msg)  //---ON or OFF--
{

    if(msg=="OFF")
    {
        stopSendingTemperature()

        MyArrows.pause()
        ButtonBase.setAttribute("fill","red")

    }
   else if(msg=="ON")
    {

        startSendingTemperature()
        if(!ScadaArrows) //---start run and initialize arrows--
        {
            runArrows()
            document.getElementById("arrowLine1").setAttribute("display","block")
            document.getElementById("arrowLine2").setAttribute("display","block")
        }
        else
            MyArrows.play()

        ButtonBase.setAttribute("fill","green")
        changeGaugeHWS(145)
    }

    buttonText.firstChild.nodeValue=msg
    buttonTextOffset.firstChild.nodeValue=msg

}


var MessageTemperature
function publishTemperature()
{
    MessageTemperature= (Math.random() * 20) + 140
    var publishConfig =
    {
        channel : HWS,  //---unique for this viewer "HWS"+timeStamp---
        message :MessageTemperature
    }
    pubnubPublish.publish(publishConfig, function(status, response)
    {
        console.log(status, response);

    })
}

function changeGaugeHWS(value)
{
    var key="gaugeHWS"
    gauges[key].redraw(value);
}
//---TEMPERATURE--
var PublishInterval
function startSendingTemperature()
{
    PublishInterval=setInterval(publishTemperature,2000)

}
function stopSendingTemperature()
{
    clearInterval(PublishInterval)
   changeGaugeHWS(80)
}

</script>
<script>

function insertFlowArrows()
{
    d3.select("#pathArrowsG").append("path")
    .attr("id","arrowLine1")
    .attr("fill","none")
    .attr("display","none")
    .attr("stroke","black")
    .attr("stroke-width","1.5")
    .attr("marker-end","url(#arrow000000)")
    .attr("d","M0,0 15,0 30,0")
    d3.select("#pathArrowsG").append("path")
    .attr("id","arrowLine2")
    .attr("fill","none")
    .attr("display","none")
    .attr("stroke","black")
    .attr("stroke-width","1.5")
    .attr("marker-end","url(#arrow000000)")
    .attr("d","M0,0 15,0 30,0")
}

var ScadaArrows=false
var MyArrows   //---onload:  MyArrows=SVG.adopt(pipe)  ---
function runArrows()
{
    var duration=5000
    var rotateAngle=5*360
    ScadaArrows=true

    var pathLength=pipe.getTotalLength()
    var arrow2Offset=pipe.getTotalLength()*.33
    MyArrows.animate(duration).during(
    function(pos) //---setter--
    {
            var length=pathLength*pos
            var Pnt0=pipe.getPointAtLength(length) //--start
            var Pnt1=pipe.getPointAtLength(length+15) //--mid---
            var Pnt2=pipe.getPointAtLength(length+30) //---end---
            var d="M"+[Pnt0.x,Pnt0.y,Pnt1.x,Pnt1.y,Pnt2.x,Pnt2.y].toString()
            arrowLine1.setAttribute("d",d)

        if(length<(pathLength-arrow2Offset))
        {
            var Pnt0=pipe.getPointAtLength(length+arrow2Offset) //--start
            var Pnt1=pipe.getPointAtLength(length+15+arrow2Offset) //--mid---
            var Pnt2=pipe.getPointAtLength(length+30+arrow2Offset) //---end---
            var d="M"+[Pnt0.x,Pnt0.y,Pnt1.x,Pnt1.y,Pnt2.x,Pnt2.y].toString()
            arrowLine2.setAttribute("d",d)
        }
        else if(length>=(pathLength-arrow2Offset))
        {
            var myLength=length-arrow2Offset
            var Pnt0=pipe.getPointAtLength(myLength-arrow2Offset) //--start
            var Pnt1=pipe.getPointAtLength(myLength+15-arrow2Offset) //--mid---
            var Pnt2=pipe.getPointAtLength(myLength+30-arrow2Offset) //---end---
            var d="M"+[Pnt0.x,Pnt0.y,Pnt1.x,Pnt1.y,Pnt2.x,Pnt2.y].toString()
            arrowLine2.setAttribute("d",d)
        }
        document.getElementById("Impeller").setAttribute("transform","rotate("+(rotateAngle*pos)+" "+cx+" "+cy+")")


    })
    .after(function(){
        runArrows()
    })
}


//==============Impeller==============
//--onload---
//---impeller rotate center point---
var cx
var cy
function placeAsImpeller()
{

    var fontSize=60
    var unicode="273D"
    var code = parseInt(unicode, 16)
    var icon = d3.select("#mySVG").append("text")
    .attr("id", "Impeller")
    .attr("x", 337)
    .attr("y", 50)
    .attr("text-anchor", "middle")
    .attr("font-size", fontSize)
    .attr("font-family", "Arial Unicode MS")
    .attr("dy",fontSize/2-4)
    .attr("stroke-width", 1.2)
    .attr("fill", "blue")
    .attr("stroke", "black")
    .text(String.fromCharCode(code))

    //---get rotate center point---
   var bb=Impeller.getBBox()

   cx=bb.x+.5*bb.width
   cy=bb.y+.5*bb.height
}


function createThisGauge() //----this application configuration----
{
    createGauge("gaugeHWS", "HWS",80,220,5,10,"#9932CC","yellow",100,[180,200],[200,220],null,"\u00B0F");
}


document.addEventListener("onload",init(),false)
var HWS
var PUMP
function init()
{


    HWS="HWS"+new Date().getTime()
    PUMP="PUMP"+new Date().getTime()

    initPublish()
    initSubscribePump()
    initSubscribeTemperature()
    createThisGauge()
    placeAsImpeller()
    insertFlowArrows()
    MyArrows=SVG.adopt(pipe)
    showSourceJS()

}

function showSource()
{
  sourceDiv.style.visibility="visible"
  sourceDiv.style.height=+sourceDiv.scrollHeight+"px"

  closeSourceButton.disabled=false
  var iframe=parent.iframe2
  var frameHeight=container.scrollHeight+100

    d3.select(parent.frame2).transition().duration(1000).attr("height",frameHeight)


}

function closeSource()
{
   d3.select("#sourceDiv").transition().duration(1000).style("height","1px")
   setTimeout('sourceDiv.style.visibility="hidden"',1000)
  closeSourceButton.disabled=true

   d3.select(parent.frame2).transition().duration(1000).attr("height",650)
}
</script>

</body>

</html>